"""
校园圈子视图
处理帖子、评论、点赞等相关的API请求
"""

from rest_framework import status, generics, permissions, filters
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from django.db.models import Count, Q
from django.shortcuts import get_object_or_404
from django.db import transaction

from .models import Category, Post, PostImage, Comment, Like, Tag, PostTag
from .serializers import (
    CategorySerializer, TagSerializer, PostListSerializer, PostDetailSerializer,
    PostCreateSerializer, CommentSerializer, LikeSerializer, PostSearchSerializer
)
from utils.response import success_response, error_response, paginated_response


class CategoryListView(generics.ListAPIView):
    """
    分类列表视图
    """
    
    permission_classes = [permissions.AllowAny]
    serializer_class = CategorySerializer
    queryset = Category.objects.filter(is_active=True)
    
    def list(self, request, *args, **kwargs):
        """获取分类列表"""
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return success_response(
            data=serializer.data,
            message="获取分类列表成功"
        )


class TagListView(generics.ListAPIView):
    """
    标签列表视图
    """
    
    permission_classes = [permissions.AllowAny]
    serializer_class = TagSerializer
    queryset = Tag.objects.all()
    
    def list(self, request, *args, **kwargs):
        """获取标签列表"""
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return success_response(
            data=serializer.data,
            message="获取标签列表成功"
        )


class PostListView(generics.ListAPIView):
    """
    帖子列表视图
    """
    
    permission_classes = [permissions.AllowAny]
    serializer_class = PostListSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['title', 'content']
    ordering_fields = ['created_at', 'like_count', 'comment_count']
    ordering = ['-created_at']
    
    def get_queryset(self):
        """获取帖子列表"""
        queryset = Post.objects.filter(status='published').select_related(
            'author', 'category'
        ).prefetch_related('post_tags__tag', 'images')
        
        # 分类筛选
        category_id = self.request.query_params.get('category')
        if category_id:
            queryset = queryset.filter(category_id=category_id)
        
        # 标签筛选
        tag_ids = self.request.query_params.getlist('tags')
        if tag_ids:
            queryset = queryset.filter(post_tags__tag__id__in=tag_ids).distinct()
        
        # 作者筛选
        author_id = self.request.query_params.get('author')
        if author_id:
            queryset = queryset.filter(author_id=author_id)
        
        # 排序
        sort_by = self.request.query_params.get('sort_by', 'latest')
        if sort_by == 'popular':
            queryset = queryset.annotate(like_count=Count('likes')).order_by('-like_count')
        elif sort_by == 'most_commented':
            queryset = queryset.annotate(comment_count=Count('comments')).order_by('-comment_count')
        
        return queryset
    
    def list(self, request, *args, **kwargs):
        """获取帖子列表"""
        queryset = self.get_queryset()
        
        # 分页
        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get('page_size', 10))
        start = (page - 1) * page_size
        end = start + page_size
        
        total_count = queryset.count()
        posts = queryset[start:end]
        
        serializer = self.get_serializer(posts, many=True)
        return paginated_response(
            data=serializer.data,
            count=total_count,
            page=page,
            page_size=page_size
        )


class PostDetailView(generics.RetrieveAPIView):
    """
    帖子详情视图
    """
    
    permission_classes = [permissions.AllowAny]
    serializer_class = PostDetailSerializer
    queryset = Post.objects.filter(status='published').select_related(
        'author', 'category'
    ).prefetch_related('post_tags__tag', 'images', 'comments')
    
    def retrieve(self, request, *args, **kwargs):
        """获取帖子详情"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return success_response(
            data=serializer.data,
            message="获取帖子详情成功"
        )


class PostCreateView(generics.CreateAPIView):
    """
    帖子创建视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = PostCreateSerializer
    
    def create(self, request, *args, **kwargs):
        """创建帖子"""
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            try:
                with transaction.atomic():
                    post = serializer.save()
                    return success_response(
                        data=PostDetailSerializer(post, context={'request': request}).data,
                        message="发布帖子成功"
                    )
            except Exception as e:
                return error_response(
                    message=f"发布帖子失败: {str(e)}",
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        else:
            return error_response(
                message="发布帖子失败",
                data=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )


class PostUpdateView(generics.UpdateAPIView):
    """
    帖子更新视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = PostCreateSerializer
    queryset = Post.objects.filter(status='published')
    
    def get_queryset(self):
        """只允许作者编辑自己的帖子"""
        return Post.objects.filter(author=self.request.user, status='published')
    
    def update(self, request, *args, **kwargs):
        """更新帖子"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        if serializer.is_valid():
            try:
                with transaction.atomic():
                    post = serializer.save()
                    return success_response(
                        data=PostDetailSerializer(post, context={'request': request}).data,
                        message="更新帖子成功"
                    )
            except Exception as e:
                return error_response(
                    message=f"更新帖子失败: {str(e)}",
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        else:
            return error_response(
                message="更新帖子失败",
                data=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )


class PostDeleteView(generics.DestroyAPIView):
    """
    帖子删除视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    queryset = Post.objects.filter(status='published')
    
    def get_queryset(self):
        """只允许作者删除自己的帖子"""
        return Post.objects.filter(author=self.request.user, status='published')
    
    def destroy(self, request, *args, **kwargs):
        """删除帖子"""
        instance = self.get_object()
        instance.status = 'deleted'
        instance.save()
        return success_response(
            message="删除帖子成功"
        )


class CommentListView(generics.ListCreateAPIView):
    """
    评论列表视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = CommentSerializer
    
    def get_queryset(self):
        """获取帖子的评论列表"""
        post_id = self.kwargs.get('post_id')
        return Comment.objects.filter(
            post_id=post_id,
            is_hidden=False,
            parent__isnull=True
        ).order_by('-created_at')
    
    def list(self, request, *args, **kwargs):
        """获取评论列表"""
        queryset = self.get_queryset()
        
        # 分页
        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get('page_size', 10))
        start = (page - 1) * page_size
        end = start + page_size
        
        total_count = queryset.count()
        comments = queryset[start:end]
        
        serializer = self.get_serializer(comments, many=True)
        return paginated_response(
            data=serializer.data,
            count=total_count,
            page=page,
            page_size=page_size
        )
    
    def create(self, request, *args, **kwargs):
        """创建评论"""
        post_id = self.kwargs.get('post_id')
        
        # 检查帖子是否允许评论
        try:
            post = Post.objects.get(id=post_id)
            if not post.allow_comment:
                return error_response(
                    message="该帖子不允许评论",
                    status_code=status.HTTP_403_FORBIDDEN
                )
        except Post.DoesNotExist:
            return error_response(
                message="帖子不存在",
                status_code=status.HTTP_404_NOT_FOUND
            )
        
        data = request.data.copy()
        data['post'] = post_id
        
        serializer = self.get_serializer(data=data)
        if serializer.is_valid():
            comment = serializer.save()
            return success_response(
                data=serializer.data,
                message="发表评论成功"
            )
        else:
            return error_response(
                message="发表评论失败",
                data=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )


class CommentDetailView(generics.RetrieveUpdateDestroyAPIView):
    """
    评论详情视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = CommentSerializer
    queryset = Comment.objects.filter(is_hidden=False)
    
    def get_queryset(self):
        """只允许作者编辑自己的评论"""
        return Comment.objects.filter(author=self.request.user, is_hidden=False)
    
    def update(self, request, *args, **kwargs):
        """更新评论"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        if serializer.is_valid():
            comment = serializer.save()
            return success_response(
                data=serializer.data,
                message="更新评论成功"
            )
        else:
            return error_response(
                message="更新评论失败",
                data=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )
    
    def destroy(self, request, *args, **kwargs):
        """删除评论"""
        instance = self.get_object()
        instance.is_hidden = True
        instance.save()
        return success_response(
            message="删除评论成功"
        )


class LikeView(APIView):
    """
    点赞视图
    """
    
    permission_classes = [permissions.IsAuthenticated]
    
    def post(self, request):
        """点赞"""
        serializer = LikeSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            like = serializer.save()
            return success_response(
                message="点赞成功"
            )
        else:
            return error_response(
                message=f"点赞失败: {str(serializer.errors)}",
                status_code=status.HTTP_400_BAD_REQUEST
            )
    
    def delete(self, request):
        """取消点赞"""
        user = request.user
        post_id = request.data.get('post')
        comment_id = request.data.get('comment')
        
        if post_id:
            like = get_object_or_404(Like, user=user, post_id=post_id)
        elif comment_id:
            like = get_object_or_404(Like, user=user, comment_id=comment_id)
        else:
            return error_response(
                message="参数错误",
                status_code=status.HTTP_400_BAD_REQUEST
            )
        
        like.delete()
        return success_response(
            message="取消点赞成功"
        )


class PostSearchView(APIView):
    """
    帖子搜索视图
    """
    
    permission_classes = [permissions.AllowAny]
    
    def get(self, request):
        """搜索帖子"""
        serializer = PostSearchSerializer(data=request.query_params)
        if serializer.is_valid():
            data = serializer.validated_data
            
            # 构建查询条件
            queryset = Post.objects.filter(status='published').select_related(
                'author', 'category'
            ).prefetch_related('post_tags__tag', 'images')
            
            # 关键词搜索
            keyword = data.get('keyword')
            if keyword:
                queryset = queryset.filter(
                    Q(title__icontains=keyword) | Q(content__icontains=keyword)
                )
            
            # 分类筛选
            category = data.get('category')
            if category:
                queryset = queryset.filter(category_id=category)
            
            # 标签筛选
            tag_ids = data.get('tag_ids', [])
            if tag_ids:
                queryset = queryset.filter(post_tags__tag__id__in=tag_ids).distinct()
            
            # 作者筛选
            author = data.get('author')
            if author:
                queryset = queryset.filter(author_id=author)
            
            # 排序
            sort_by = data.get('sort_by', 'latest')
            if sort_by == 'popular':
                queryset = queryset.annotate(like_count=Count('likes')).order_by('-like_count')
            elif sort_by == 'most_commented':
                queryset = queryset.annotate(comment_count=Count('comments')).order_by('-comment_count')
            else:
                queryset = queryset.order_by('-created_at')
            
            # 分页
            page = data.get('page', 1)
            page_size = data.get('page_size', 10)
            start = (page - 1) * page_size
            end = start + page_size
            
            total_count = queryset.count()
            posts = queryset[start:end]
            
            serializer = PostListSerializer(posts, many=True, context={'request': request})
            return paginated_response(
                data=serializer.data,
                count=total_count,
                page=page,
                page_size=page_size
            )
        else:
            return error_response(
                message="搜索参数错误",
                data=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )


@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def user_posts_view(request, user_id):
    """
    获取用户发布的帖子
    """
    posts = Post.objects.filter(
        author_id=user_id,
        status='published'
    ).select_related('author', 'category').prefetch_related('post_tags__tag', 'images')
    
    # 分页
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 10))
    start = (page - 1) * page_size
    end = start + page_size
    
    total_count = posts.count()
    posts = posts[start:end]
    
    serializer = PostListSerializer(posts, many=True, context={'request': request})
    return paginated_response(
        data=serializer.data,
        count=total_count,
        page=page,
        page_size=page_size
    )


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def user_liked_posts_view(request):
    """
    获取用户点赞的帖子
    """
    liked_posts = Post.objects.filter(
        likes__user=request.user,
        status='published'
    ).select_related('author', 'category').prefetch_related('post_tags__tag', 'images')
    
    # 分页
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 10))
    start = (page - 1) * page_size
    end = start + page_size
    
    total_count = liked_posts.count()
    posts = liked_posts[start:end]
    
    serializer = PostListSerializer(posts, many=True, context={'request': request})
    return paginated_response(
        data=serializer.data,
        count=total_count,
        page=page,
        page_size=page_size
    )
